home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / gui / gtlayout.lha / Source / LTP_LayoutGadgets.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-09  |  29.3 KB  |  1,126 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #include "Assert.h"
  15.  
  16. #ifdef DO_BOOPSI_KIND    /* Support code */
  17.  
  18. /*****************************************************************************/
  19.  
  20. #include <dos/dosextens.h>
  21.  
  22. /*****************************************************************************/
  23.  
  24. STATIC VOID
  25. LocalAddPart(STRPTR Base,STRPTR Name)
  26. {
  27.     LONG Len = strlen(Base);
  28.  
  29.     if(Base[Len - 1] != ':')
  30.         strcat(Base,"/");
  31.  
  32.     strcat(Base,Name);
  33. }
  34.  
  35. STATIC struct Library *
  36. OpenClass(STRPTR Name)
  37. {
  38.     struct Library *Result;
  39.  
  40.     Result = OpenLibrary(Name,0);
  41.     if(Result == NULL)
  42.     {
  43.         struct Process *    Process = (struct Process *)FindTask(NULL);
  44.         UBYTE                LocalBuffer[256];
  45.         LONG                i,Len;
  46.  
  47.         Len = strlen(Name);
  48.  
  49.         for(i = Len - 1 ; i >= 0 ; i--)
  50.         {
  51.             if(Name[i] == '/' || Name[i] == ':')
  52.             {
  53.                 Name = &Name[i + 1];
  54.  
  55.                 break;
  56.             }
  57.         }
  58.  
  59.         if(Process->pr_Task.tc_Node.ln_Type == NT_PROCESS && Process->pr_HomeDir != NULL)
  60.         {
  61.             strcpy(LocalBuffer,"PROGDIR:Classes/Gadgets");
  62.             LocalAddPart(LocalBuffer,Name);
  63.  
  64.             Result = OpenLibrary(LocalBuffer,0);
  65.         }
  66.  
  67.         if(!Result)
  68.         {
  69.             strcpy(LocalBuffer,":Classes/Gadgets");
  70.             LocalAddPart(LocalBuffer,Name);
  71.  
  72.             if(!(Result = OpenLibrary(LocalBuffer,0)))
  73.             {
  74.                 strcpy(LocalBuffer,"Gadgets");
  75.                 LocalAddPart(LocalBuffer,Name);
  76.  
  77.                 if(!(Result = OpenLibrary(LocalBuffer,0)))
  78.                     Result = OpenLibrary(Name,0);
  79.             }
  80.         }
  81.     }
  82.  
  83.     return(Result);
  84. }
  85.  
  86. #endif    /* DO_BOOPSI_KIND */
  87.  
  88.  
  89. /*****************************************************************************/
  90.  
  91.  
  92. VOID
  93. LTP_LayoutGadgets(LayoutHandle *Handle,ObjectNode *Group,LONG Left,LONG Top,LONG PlusWidth,LONG PlusHeight)
  94. {
  95.     if(!Handle->Failed)
  96.     {
  97.         STATIC const struct TagItem NoUnderscoreVanillaTags[] =
  98.         {
  99.             {TAG_DONE}
  100.         };
  101.  
  102.         STATIC const struct TagItem VanillaTags[] =
  103.         {
  104.             {GT_Underscore, '_'},
  105.             {TAG_DONE}
  106.         };
  107.  
  108.         STATIC const struct TagItem DisabledTags[] =
  109.         {
  110.             {GT_Underscore, '_' },
  111.             {GA_Disabled,    TRUE},
  112.             {TAG_DONE}
  113.         };
  114.  
  115.         STATIC const struct TagItem NoUnderscoreDisabledTags[] =
  116.         {
  117.             {GA_Disabled,    TRUE},
  118.             {TAG_DONE}
  119.         };
  120.  
  121.         struct NewGadget    NewGadget;
  122.  
  123.         struct Gadget *        Gadget;
  124.         struct Gadget *        Extra;
  125.         struct TagItem *    Tags;
  126.         ULONG                page;
  127.         ObjectNode *        Node;
  128.  
  129.         if(!Handle->List)
  130.         {
  131.             if(!(Handle->Previous = CreateContext(&Handle->List)))
  132.             {
  133.                 Handle->Failed = TRUE;
  134.  
  135.                 return;
  136.             }
  137.         }
  138.  
  139.         NewGadget.ng_TextAttr   = Handle->TextAttr;
  140.         NewGadget.ng_VisualInfo = Handle->VisualInfo;
  141.  
  142.         Group->Special.Group.Visible = TRUE;
  143.  
  144.         SCANPAGE(Group,Node,page)
  145.         {
  146.             if(Node->Type != FRAME_KIND && Node->Type != IMAGE_KIND && Node->Type != BLANK_KIND && Node->Type != BOX_KIND && Node->Type != XBAR_KIND && Node->Type != YBAR_KIND)
  147.             {
  148.                 Extra = NULL;
  149.  
  150.                 if(Node->GroupIndent)
  151.                 {
  152.                     NewGadget.ng_LeftEdge     = Node->Left + 4;
  153.                     NewGadget.ng_TopEdge    = Node->Top + 2;
  154.                     NewGadget.ng_Width        = Node->Width - (4 + 4);
  155.                     NewGadget.ng_Height        = Node->Height - (2 + 2);
  156.                 }
  157.                 else
  158.                 {
  159.                     NewGadget.ng_LeftEdge     = Node->Left;
  160.                     NewGadget.ng_TopEdge    = Node->Top;
  161.                     NewGadget.ng_Width        = Node->Width;
  162.                     NewGadget.ng_Height        = Node->Height;
  163.                 }
  164.  
  165.                 NewGadget.ng_GadgetText    = Node->Label ? Node->Label : (STRPTR)"";
  166.                 NewGadget.ng_GadgetID     = Node->ID;
  167.                 NewGadget.ng_UserData     = Node;
  168.  
  169.                 if(Node->NoKey)
  170.                 {
  171.                     if(Node->Disabled)
  172.                     {
  173.                         if(!V39 && (Node->Type == MX_KIND || Node->Type == LISTVIEW_KIND))
  174.                             Tags = (struct TagItem *)NoUnderscoreVanillaTags;
  175.                         else
  176.                             Tags = (struct TagItem *)NoUnderscoreDisabledTags;
  177.                     }
  178.                     else
  179.                         Tags = (struct TagItem *)NoUnderscoreVanillaTags;
  180.                 }
  181.                 else
  182.                 {
  183.                     if(Node->Disabled)
  184.                     {
  185.                         if(!V39 && (Node->Type == MX_KIND || Node->Type == LISTVIEW_KIND))
  186.                             Tags = (struct TagItem *)VanillaTags;
  187.                         else
  188.                             Tags = (struct TagItem *)DisabledTags;
  189.                     }
  190.                     else
  191.                         Tags = (struct TagItem *)VanillaTags;
  192.                 }
  193.  
  194.                 switch(Node->LabelPlace)
  195.                 {
  196.                     case PLACE_LEFT:
  197.  
  198.                         NewGadget.ng_Flags = PLACETEXT_LEFT;
  199.                         break;
  200.  
  201.                     case PLACE_RIGHT:
  202.  
  203.                         NewGadget.ng_Flags = PLACETEXT_RIGHT;
  204.                         break;
  205.  
  206.                     case PLACE_ABOVE:
  207.  
  208.                         NewGadget.ng_Flags = PLACETEXT_ABOVE;
  209.                         break;
  210.  
  211.                     case PLACE_BELOW:
  212.  
  213.                         NewGadget.ng_Flags = PLACETEXT_BELOW;
  214.                         break;
  215.  
  216.                     case PLACE_IN:
  217.  
  218.                         NewGadget.ng_Flags = PLACETEXT_IN;
  219.                         break;
  220.  
  221.                     default:
  222.  
  223.                         NewGadget.ng_Flags = NULL;
  224.                         break;
  225.                 }
  226.  
  227.                 if(Node->HighLabel)
  228.                     NewGadget.ng_Flags |= NG_HIGHLABEL;
  229.  
  230.                 Gadget = NULL; /* Always initialize this before entering the switch table. */
  231.  
  232.                 switch(Node->Type)
  233.                 {
  234.                     #ifdef DO_BOOPSI_KIND
  235.                     {
  236.                         case BOOPSI_KIND:
  237.                         {
  238.                             struct Gadget *Link;
  239.  
  240.                             if(Node->Special.BOOPSI.Link != NIL_LINK && Node->Special.BOOPSI.TagLink)
  241.                             {
  242.                                 if(!(Link = LTP_FindGadgetLinear(Handle,Node->Special.BOOPSI.Link)))
  243.                                 {
  244.                                     Handle->Failed = TRUE;
  245.  
  246.                                     return;    /* Note: must return since we are in a loop that
  247.                                              *       creates all gadgets for the current page.
  248.                                              */
  249.                                 }
  250.                             }
  251.                             else
  252.                                 Link = NULL;
  253.  
  254.                             if(Node->Special.BOOPSI.ClassLibraryName)
  255.                             {
  256.                                 if(!(Node->Special.BOOPSI.ClassBase = OpenClass(Node->Special.BOOPSI.ClassLibraryName)))
  257.                                 {
  258.                                     break;
  259.                                 }
  260.                             }
  261.  
  262.                             if(Node->Special.BOOPSI.FullWidth)
  263.                             {
  264.                                 NewGadget.ng_LeftEdge    = Node->Special.BOOPSI.Parent->Left;
  265.                                 NewGadget.ng_Width        = Node->Special.BOOPSI.Parent->Width;
  266.                             }
  267.  
  268.                             if(Node->Special.BOOPSI.FullHeight)
  269.                             {
  270.                                 NewGadget.ng_TopEdge    = Node->Special.BOOPSI.Parent->Top;
  271.                                 NewGadget.ng_Height        = Node->Special.BOOPSI.Parent->Height;
  272.                             }
  273.  
  274.                             Gadget = NewObject(Node->Special.BOOPSI.ClassInstance,Node->Special.BOOPSI.ClassName,
  275.                                 GA_Left,        NewGadget.ng_LeftEdge,
  276.                                 GA_Top,            NewGadget.ng_TopEdge,
  277.                                 GA_Width,        NewGadget.ng_Width,
  278.                                 GA_Height,        NewGadget.ng_Height,
  279.                                 GA_Disabled,    Node->Disabled,
  280.                                 GA_ID,            Node->ID,
  281.                                 GA_UserData,    Node,
  282.  
  283.                                 Link ? Node->Special.BOOPSI.TagLink : TAG_IGNORE,                                    Link,
  284.                                 Handle->BOOPSIPrevious ? GA_Previous : TAG_IGNORE,                                    Handle->BOOPSIPrevious,
  285.                                 Node->Special.BOOPSI.TagTextAttr ? Node->Special.BOOPSI.TagTextAttr : TAG_IGNORE,    Handle->TextAttr,
  286.                                 Node->Special.BOOPSI.TagDrawInfo ? Node->Special.BOOPSI.TagDrawInfo : TAG_IGNORE,    Handle->DrawInfo,
  287.                                 Node->Special.BOOPSI.TagScreen ? Node->Special.BOOPSI.TagScreen : TAG_IGNORE,        Handle->Screen,
  288.                                 Node->Special.BOOPSI.ClassTags ? TAG_MORE : TAG_DONE,                                Node->Special.BOOPSI.ClassTags);
  289.  
  290.                             break;
  291.                         }
  292.                     }
  293.                     #endif /* DO_BOOPSI_KIND */
  294.  
  295.                     #ifdef DO_POPUP_KIND
  296.                     {
  297.                         case POPUP_KIND:
  298.  
  299.                             Gadget = NewObject(LTP_PopupClass,NULL,
  300.                                 GA_Left,            NewGadget.ng_LeftEdge,
  301.                                 GA_Top,                NewGadget.ng_TopEdge,
  302.                                 GA_Width,            NewGadget.ng_Width,
  303.                                 GA_Height,            NewGadget.ng_Height,
  304.                                 GA_Disabled,        Node->Disabled,
  305.                                 GA_ID,                Node->ID,
  306.                                 GA_UserData,        Node,
  307.                                 GA_RelVerify,        TRUE,
  308.                                 PIA_Labels,            Node->Special.Popup.Choices,
  309.                                 PIA_Active,            Node->Current,
  310.                                 PIA_Font,            Handle->TextAttr,
  311.                                 PIA_CentreActive,    Node->Special.Popup.CentreActive,
  312.                                 PIA_AspectX,        Handle->AspectX,
  313.                                 PIA_AspectY,        Handle->AspectY,
  314.  
  315.                                 Handle->BOOPSIPrevious ? GA_Previous : TAG_IGNORE,Handle->BOOPSIPrevious,
  316.                             TAG_DONE);
  317.  
  318.                             break;
  319.                     }
  320.                     #endif /* DO_POPUP_KIND */
  321.  
  322.                     #ifdef DO_TAB_KIND
  323.                     {
  324.                         case TAB_KIND:
  325.  
  326.                             if(Node->Special.Tab.FullWidth)
  327.                             {
  328.                                 NewGadget.ng_LeftEdge    = Handle->TopGroup->Left    - Left;
  329.                                 NewGadget.ng_Width        = Handle->TopGroup->Width    + PlusWidth;
  330.  
  331.                                 NewGadget.ng_LeftEdge    += Handle->Screen->WBorLeft;
  332.                                 NewGadget.ng_Width        -= Handle->Screen->WBorLeft + Handle->Screen->WBorRight;
  333.                             }
  334.                             else
  335.                             {
  336.                                 NewGadget.ng_LeftEdge    = Node->Special.Tab.Parent->Left;
  337.                                 NewGadget.ng_Width        = Node->Special.Tab.Parent->Width;
  338.                             }
  339.  
  340.                             Gadget = NewObject(LTP_TabClass,NULL,
  341.                                 GA_Left,        NewGadget.ng_LeftEdge,
  342.                                 GA_Top,            NewGadget.ng_TopEdge,
  343.                                 GA_Width,        NewGadget.ng_Width,
  344.                                 GA_Height,        NewGadget.ng_Height,
  345.                                 GA_Disabled,    Node->Disabled,
  346.                                 GA_ID,            Node->ID,
  347.                                 GA_UserData,    Node,
  348.                                 GA_RelVerify,    TRUE,
  349.                                 TIA_Labels,        Node->Special.Popup.Choices,
  350.                                 TIA_Index,        Node->Current,
  351.                                 TIA_Font,        Handle->TextAttr,
  352.                                 TIA_DrawInfo,    Handle->DrawInfo,
  353.                                 TIA_Screen,        Handle->Screen,
  354.  
  355.                                 Handle->BOOPSIPrevious ? GA_Previous : TAG_IGNORE,Handle->BOOPSIPrevious,
  356.                             TAG_DONE);
  357.  
  358.                             break;
  359.                     }
  360.                     #endif    // DO_TAB_KIND
  361.  
  362.                     #ifdef DO_LEVEL_KIND
  363.                     {
  364.                         case LEVEL_KIND:
  365.                         {
  366.                             LONG Current;
  367.  
  368.                             if(Node->Special.Level.Freedom == FREEHORIZ)
  369.                                 Current = Node->Current;
  370.                             else
  371.                                 Current = Node->Max - Node->Current;
  372.  
  373.                             Gadget = NewObject(LTP_LevelClass,NULL,
  374.                                 GA_Left,        NewGadget.ng_LeftEdge,
  375.                                 GA_Top,            NewGadget.ng_TopEdge,
  376.                                 GA_Width,        NewGadget.ng_Width,
  377.                                 GA_Height,        NewGadget.ng_Height,
  378.                                 GA_Disabled,    Node->Disabled,
  379.                                 GA_ID,            Node->ID,
  380.                                 GA_UserData,    Node,
  381.                                 GA_RelVerify,    TRUE,
  382.                                 GA_Immediate,    TRUE,
  383.                                 GA_FollowMouse,    TRUE,
  384.                                 PGA_Freedom,    Node->Special.Level.Freedom,
  385.                                 SLA_UseTicks,    Node->Special.Level.Ticks,
  386.                                 SLA_NumTicks,    Node->Special.Level.NumTicks,
  387.                                 SLA_DrawInfo,    Handle->DrawInfo,
  388.                                 SLA_Current,    Current        - Node->Special.Level.Plus,
  389.                                 SLA_Max,        Node->Max    - Node->Special.Level.Plus,
  390.                                 SLA_Reference,    Handle->GlyphHeight,
  391.  
  392.                                 Handle->BOOPSIPrevious ? GA_Previous : TAG_IGNORE,Handle->BOOPSIPrevious,
  393.                             TAG_DONE);
  394.  
  395.                             if(Gadget != NULL)
  396.                             {
  397.                                 if(Node->Special.Level.Freedom == FREEHORIZ)
  398.                                 {
  399.                                     SetAttrs(Gadget,
  400.                                         GA_Top, NewGadget.ng_TopEdge + (Node->Height - Gadget->Height) / 2,
  401.                                     TAG_DONE);
  402.                                 }
  403.                                 else
  404.                                 {
  405.                                     SetAttrs(Gadget,
  406.                                         GA_Left, NewGadget.ng_LeftEdge + (Node->Width - Gadget->Width) / 2,
  407.                                     TAG_DONE);
  408.                                 }
  409.                             }
  410.  
  411.                             break;
  412.                         }
  413.                     }
  414.                     #endif    /* DO_LEVEL_KIND */
  415.  
  416.                     case BUTTON_KIND:
  417.                     {
  418.                         register BOOL IsNonStandardButton;
  419.  
  420.                         #ifdef OLD_STYLE_DEFAULT_KEY
  421.                         {
  422.                             IsNonStandardButton = (BOOL)(Node->Special.Button.Lines != NULL);
  423.                         }
  424.                         #else
  425.                         {
  426.                             IsNonStandardButton = (BOOL)(    (Node->Special.Button.Lines != NULL) ||
  427.                                                             (Node->Special.Button.ReturnKey != NULL)
  428.                                                         );
  429.                         }
  430.                         #endif /* OLD_STYLE_DEFAULT_KEY */
  431.  
  432.                         if(IsNonStandardButton)
  433.                         {
  434.                             #ifndef OLD_STYLE_DEFAULT_KEY
  435.                             {
  436.                                 if(Node->Special.Button.ReturnKey)
  437.                                     Handle->TextAttr->ta_Style |= FSF_BOLD;
  438.                             }
  439.                             #endif    /* !OLD_STYLE_DEFAULT_KEY */
  440.  
  441.                             if(Node->Special.Button.ButtonImage = NewObject(LTP_ImageClass,NULL,
  442.                                 IIA_ImageType,    IMAGECLASS_MULTILINEBUTTON,
  443.                                 IIA_Lines,        Node->Special.Button.Lines,
  444.                                 IIA_LineCount,    Node->Special.Button.LineCount,
  445.                                 IIA_KeyStroke,    Node->Special.Button.KeyStroke,
  446.                                 IIA_Emboss,        Node->Special.Button.ReturnKey,
  447.                                 IIA_Label,        Node->Label,
  448.                                 IIA_Font,        Handle->TextAttr,
  449.                                 IA_Width,        NewGadget.ng_Width,
  450.                                 IA_Height,        NewGadget.ng_Height,
  451.                             TAG_DONE))
  452.                             {
  453.                                 NewGadget.ng_GadgetText    = "";
  454.                                 NewGadget.ng_Flags        = NULL;
  455.  
  456.                                 if(Gadget = CreateGadgetA(GENERIC_KIND,Handle->Previous,&NewGadget,NULL))
  457.                                 {
  458.                                     Gadget->GadgetType        |= GTYP_BOOLGADGET;
  459.  
  460.                                     Gadget->Flags             = GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  461.                                     Gadget->Activation        = GACT_RELVERIFY;
  462.  
  463.                                     Gadget->GadgetRender    = Node->Special.Button.ButtonImage;
  464.                                     Gadget->SelectRender    = Node->Special.Button.ButtonImage;
  465.  
  466.                                     if(Node->Disabled)
  467.                                         Gadget->Flags |= GFLG_DISABLED;
  468.                                 }
  469.                             }
  470.  
  471.                             #ifndef OLD_STYLE_DEFAULT_KEY
  472.                             {
  473.                                 if(Node->Special.Button.ReturnKey)
  474.                                     Handle->TextAttr->ta_Style &= ~FSF_BOLD;
  475.                             }
  476.                             #endif    /* !OLD_STYLE_DEFAULT_KEY */
  477.                         }
  478.                         else
  479.                         {
  480.                             Gadget = CreateGadgetA(BUTTON_KIND,Handle->Previous,&NewGadget,Tags);
  481.                         }
  482.  
  483.                         break;
  484.                     }
  485.  
  486.                     case GROUP_KIND:
  487.  
  488.                         LTP_LayoutGadgets(Handle,Node,Left,Top,PlusWidth,PlusHeight);
  489.  
  490.                         continue;
  491.  
  492.                     case CHECKBOX_KIND:
  493.  
  494.                         Gadget = CreateGadget(CHECKBOX_KIND,Handle->Previous,&NewGadget,
  495.                             GTCB_Checked,    Node->Current,
  496.                             GTCB_Scaled,    TRUE,
  497.                         TAG_MORE,Tags);
  498.  
  499.                         break;
  500.  
  501.                     case LISTVIEW_KIND:
  502.                     {
  503.                         struct TextFont *LocalFont = NULL;
  504.                         ULONG WhichTag;
  505.                         struct Gadget * LinkedGadget;
  506.  
  507.                         if(!Node->Special.List.ReadOnly && Node->Special.List.LinkID != -1 && Node->Special.List.LinkID != NIL_LINK)
  508.                             LinkedGadget = Node->Special.List.Link = LTP_FindGadgetLinear(Handle,Node->Special.List.LinkID);
  509.                         else
  510.                             LinkedGadget = NULL;
  511.  
  512.                         if((NewGadget.ng_Flags & PLACETEXT_ABOVE) && Node->Label && Node->Special.List.FlushLabelLeft)
  513.                             NewGadget.ng_GadgetText = "";
  514.  
  515.                         if(Node->Special.List.TextAttr)
  516.                         {
  517.                                 // Use the system default font?
  518.  
  519.                             if(Node->Special.List.TextAttr == (struct TextAttr *)~0)
  520.                             {
  521.                                 Forbid();
  522.  
  523.                                 LTP_GetDefaultFont(&Handle->FixedFont);
  524.  
  525.                                 if(!(LocalFont = OpenFont((struct TextAttr *)&Handle->FixedFont)))
  526.                                 {
  527.                                     Permit();
  528.  
  529.                                     Handle->Failed = TRUE;
  530.  
  531.                                     break;
  532.                                 }
  533.  
  534.                                 NewGadget.ng_TextAttr = (struct TextAttr *)&Handle->FixedFont;
  535.                             }
  536.                             else
  537.                             {
  538.                                 NewGadget.ng_TextAttr = Node->Special.List.TextAttr;
  539.                             }
  540.  
  541.                             NewGadget.ng_GadgetText = "";
  542.                         }
  543.  
  544.                         if(V39)
  545.                             WhichTag = GTLV_MakeVisible;
  546.                         else
  547.                             WhichTag = GTLV_Top;
  548.  
  549.                         Gadget = CreateGadget(LISTVIEW_KIND,Handle->Previous,&NewGadget,
  550.                             GTLV_Selected,        Node->Current,
  551.                             GTLV_ReadOnly,        Node->Special.List.ReadOnly,
  552.                             GTLV_ScrollWidth,    2 + 2 * Handle->GlyphWidth + 2,
  553.  
  554.                             Node->Current >= 0 ? WhichTag : TAG_IGNORE,                            Node->Current,
  555.                             Node->Special.List.Labels ? GTLV_Labels : TAG_IGNORE,                Node->Special.List.Labels,
  556.                             Node->Special.List.LinkID != -1 ? GTLV_ShowSelected : TAG_IGNORE,    LinkedGadget,
  557.                             Node->Special.List.CallBack ?    GTLV_CallBack : TAG_IGNORE,            Node->Special.List.CallBack,
  558.                             Node->Special.List.MaxPen ?    GTLV_MaxPen : TAG_IGNORE,                Node->Special.List.MaxPen,
  559.                         TAG_MORE,Tags);
  560.  
  561.                         if(Node->Special.List.TextAttr)
  562.                         {
  563.                             NewGadget.ng_TextAttr = Handle->TextAttr;
  564.  
  565.                             if(LocalFont)
  566.                             {
  567.                                 CloseFont(LocalFont);
  568.  
  569.                                 Permit();
  570.                             }
  571.                         }
  572.  
  573.                         break;
  574.                     }
  575.  
  576.                     case MX_KIND:
  577.  
  578.                         NewGadget.ng_Height = Handle->GlyphHeight;
  579.  
  580.                         Gadget = CreateGadget(MX_KIND,Handle->Previous,&NewGadget,
  581.                             GTMX_Labels,    Node->Special.Radio.Choices,
  582.                             GTMX_Active,    Node->Current,
  583.                             GTMX_Spacing,    Handle->InterHeight,
  584.                             GTMX_Scaled,    TRUE,
  585.  
  586.                             Node->Label ? GTMX_TitlePlace : TAG_IGNORE,  Node->Special.Radio.TitlePlace,
  587.                         TAG_MORE,Tags);
  588.  
  589.                         break;
  590.  
  591.                     case TEXT_KIND:
  592.  
  593.                         if(Node->Special.Text.UsePicker)
  594.                             NewGadget.ng_Width -= LTP_GetPickerSize(Handle);
  595.  
  596.                         if(Gadget = CreateGadget(TEXT_KIND,Handle->Previous,&NewGadget,
  597.                             GTTX_Border,        Node->Special.Text.Border,
  598.                             GTTX_Justification,    Node->Special.Text.Justification,
  599.                             GTTX_Clipped,        TRUE,
  600.  
  601.                             Node->Special.Text.Text ? GTTX_Text : TAG_IGNORE,Node->Special.Text.Text,
  602.                             Node->Special.Text.FrontPen != -1 ? GTTX_FrontPen : TAG_IGNORE,Node->Special.Text.FrontPen,
  603.                             Node->Special.Text.BackPen != -1 ? GTTX_BackPen : TAG_IGNORE,Node->Special.Text.BackPen,
  604.                         TAG_MORE,Tags))
  605.                         {
  606.                             if(Node->Special.Text.UsePicker)
  607.                             {
  608.                                 Handle->Previous = Gadget;
  609.  
  610.                                 Extra = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_PICKER,0);
  611.  
  612.                                 if(!Extra)
  613.                                     Gadget = NULL;
  614.  
  615.                                 Node->Special.Text.Picker = Extra;
  616.                             }
  617.                         }
  618.  
  619.                         break;
  620.  
  621.                     #ifdef DO_GAUGE_KIND
  622.                     {
  623.                         case GAUGE_KIND:
  624.  
  625.                             NewGadget.ng_Height -= Handle->InterHeight + Handle->GlyphHeight + 2;
  626.  
  627.                             Gadget = CreateGadgetA(TEXT_KIND,Handle->Previous,&NewGadget,NULL);
  628.  
  629.                             break;
  630.                     }
  631.                     #endif
  632.  
  633.                     #ifdef DO_TAPEDECK_KIND
  634.                     {
  635.                         case TAPEDECK_KIND:
  636.  
  637.                             if(Node->Special.TapeDeck.ButtonType >= TDBT_BACKWARD && Node->Special.TapeDeck.ButtonType < TDBTLAST)
  638.                             {
  639.                                 LONG    ImageType;
  640.                                 LONG    Activation,
  641.                                         Flags;
  642.  
  643.                                 if(Node->Special.TapeDeck.Toggle)
  644.                                     Activation = GACT_TOGGLESELECT | GACT_IMMEDIATE;
  645.                                 else
  646.                                 {
  647.                                     if(Node->Special.TapeDeck.Tick)
  648.                                     {
  649.                                         Activation = GACT_RELVERIFY | GACT_IMMEDIATE;
  650.  
  651.                                         Handle->IDCMP |= IDCMP_GADGETDOWN | IDCMP_GADGETUP | IDCMP_INTUITICKS;
  652.                                     }
  653.                                     else
  654.                                         Activation = GACT_RELVERIFY;
  655.                                 }
  656.  
  657.                                 if(Node->Current)
  658.                                     Flags = GFLG_GADGIMAGE | GFLG_GADGHIMAGE | GFLG_SELECTED;
  659.                                 else
  660.                                     Flags = GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  661.  
  662.                                 switch(Node->Special.TapeDeck.ButtonType)
  663.                                 {
  664.                                     case TDBT_BACKWARD:
  665.  
  666.                                         ImageType = IMAGECLASS_BACKWARD;
  667.                                         break;
  668.  
  669.                                     case TDBT_FORWARD:
  670.  
  671.                                         ImageType = IMAGECLASS_FORWARD;
  672.                                         break;
  673.  
  674.                                     case TDBT_PREVIOUS:
  675.  
  676.                                         ImageType = IMAGECLASS_PREVIOUS;
  677.                                         break;
  678.  
  679.                                     case TDBT_NEXT:
  680.  
  681.                                         ImageType = IMAGECLASS_NEXT;
  682.                                         break;
  683.  
  684.                                     case TDBT_RECORD:
  685.  
  686.                                         ImageType = IMAGECLASS_RECORD;
  687.                                         break;
  688.  
  689.                                     case TDBT_PLAY:
  690.  
  691.                                         ImageType = IMAGECLASS_PLAY;
  692.                                         break;
  693.  
  694.                                     case TDBT_STOP:
  695.  
  696.                                         ImageType = IMAGECLASS_STOP;
  697.                                         break;
  698.  
  699.                                     case TDBT_PAUSE:
  700.  
  701.                                         ImageType = IMAGECLASS_PAUSE;
  702.                                         break;
  703.  
  704.                                     case TDBT_REWIND:
  705.  
  706.                                         ImageType = IMAGECLASS_REWIND;
  707.                                         break;
  708.  
  709.                                     case TDBT_EJECT:
  710.  
  711.                                         ImageType = IMAGECLASS_EJECT;
  712.                                         break;
  713.  
  714.                                     default:    /* Should never happen! */
  715.  
  716.                                         ImageType = -1;
  717.                                         break;
  718.                                 }
  719.  
  720.                                 if(ImageType != -1)
  721.                                 {
  722.                                     if(Node->Special.TapeDeck.ButtonImage = NewObject(LTP_ImageClass,NULL,
  723.                                         IIA_ImageType,    ImageType,
  724.                                         IIA_GlyphWidth, Node->Special.TapeDeck.ButtonWidth,
  725.                                         IIA_GlyphHeight,Node->Special.TapeDeck.ButtonHeight,
  726.                                         IA_Width,        NewGadget.ng_Width,
  727.                                         IA_Height,        NewGadget.ng_Height,
  728.                                     TAG_DONE))
  729.                                     {
  730.                                         NewGadget.ng_GadgetText    = "";
  731.                                         NewGadget.ng_Flags        = NULL;
  732.  
  733.                                         if(Gadget = CreateGadgetA(GENERIC_KIND,Handle->Previous,&NewGadget,NULL))
  734.                                         {
  735.                                             Gadget->GadgetType        |= GTYP_BOOLGADGET;
  736.                                             Gadget->Flags             |= Flags;
  737.                                             Gadget->Activation        |= Activation;
  738.  
  739.                                             Gadget->GadgetRender     = Node->Special.TapeDeck.ButtonImage;
  740.                                             Gadget->SelectRender     = Node->Special.TapeDeck.ButtonImage;
  741.  
  742.                                             if(Node->Disabled)
  743.                                                 Gadget->Flags |= GFLG_DISABLED;
  744.                                         }
  745.                                     }
  746.                                 }
  747.                             }
  748.  
  749.                             break;
  750.                     }
  751.                     #endif    /* DO_TAPEDECK_KIND */
  752.  
  753.                     case NUMBER_KIND:
  754.  
  755.                         Gadget = CreateGadget(NUMBER_KIND,Handle->Previous,&NewGadget,
  756.                             GTNM_Number,        Node->Special.Number.Number,
  757.                             GTNM_Border,        Node->Special.Number.Border,
  758.                             GTNM_Justification,    Node->Special.Number.Justification,
  759.                             GTNM_Border,        Node->Special.Number.Border,
  760.                             GTNM_Format,        Node->Special.Number.Format ? Node->Special.Number.Format : (STRPTR)"%ld",
  761.                             GTNM_Clipped,        TRUE,
  762.                             GTNM_MaxNumberLen,    Node->Special.Number.MaxNumberLen,
  763.  
  764.                             Node->Special.Number.FrontPen != -1 ? GTNM_FrontPen : TAG_IGNORE,Node->Special.Number.FrontPen,
  765.                             Node->Special.Number.BackPen != -1 ? GTNM_BackPen : TAG_IGNORE,Node->Special.Number.BackPen,
  766.                         TAG_MORE,Tags);
  767.  
  768.                         break;
  769.  
  770.                     case CYCLE_KIND:
  771.  
  772.                         Gadget = CreateGadget(CYCLE_KIND,Handle->Previous,&NewGadget,
  773.                             GTCY_Labels,        Node->Special.Cycle.Choices,
  774.                             GTCY_Active,        Node->Current,
  775.                         TAG_MORE,Tags);
  776.  
  777.                         break;
  778.  
  779.                     case PALETTE_KIND:
  780.  
  781.                         if(Node->Special.Palette.UsePicker)
  782.                         {
  783.                             NewGadget.ng_Width = Node->Special.Palette.IndicatorWidth;
  784.  
  785.                             if(Gadget = CreateGadget(TEXT_KIND,Handle->Previous,&NewGadget,TAG_MORE,Tags))
  786.                             {
  787.                                 Handle->Previous = Gadget;
  788.  
  789.                                 Extra = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_PICKER,0);
  790.  
  791.                                 if(!Extra)
  792.                                     Gadget = NULL;
  793.  
  794.                                 Node->Special.Palette.Picker = Extra;
  795.                             }
  796.                         }
  797.                         else
  798.                         {
  799.                             Gadget = CreateGadget(PALETTE_KIND,Handle->Previous,&NewGadget,
  800.                                 GTPA_Depth,                Node->Special.Palette.Depth,
  801.                                 GTPA_Color,                Node->Current,
  802.                                 GTPA_ColorOffset,        Node->Min,
  803.                                 GTPA_IndicatorWidth,    max(10,Node->Width / (Node->Max - Node->Min + 1)),
  804.                                 GTPA_IndicatorHeight,    Node->Height,
  805.  
  806.                                 Node->Special.Palette.ColourTable ? GTPA_ColorTable : TAG_IGNORE,Node->Special.Palette.ColourTable,
  807.                             TAG_MORE,Tags);
  808.                         }
  809.  
  810.                         break;
  811.  
  812.                     case SLIDER_KIND:
  813.  
  814.                         Gadget = CreateGadget(SLIDER_KIND,Handle->Previous,&NewGadget,
  815.                             GTSL_Min,            Node->Min,
  816.                             GTSL_Max,            Node->Max,
  817.                             GTSL_Level,            Node->Current,
  818.                             GTSL_MaxLevelLen,    Node->Special.Slider.MaxLevelLen,
  819.                             GTSL_LevelPlace,    Node->Special.Slider.LevelPlace,
  820.                             GTSL_LevelFormat,    Node->Special.Slider.LevelFormat ? Node->Special.Slider.LevelFormat : (STRPTR)"%ld",
  821.                             GA_RelVerify,        TRUE,
  822.  
  823.                             V40 ? GTSL_MaxPixelLen : TAG_IGNORE,                        Node->Special.Slider.LevelWidth,
  824.                             V40 ? GTSL_Justification : TAG_IGNORE,                        GTJ_RIGHT,
  825.                             Node->Special.Slider.DispFunc ? GTSL_DispFunc : TAG_IGNORE,    Node->Special.Slider.DispFunc,
  826.                         TAG_MORE,Tags);
  827.  
  828.                         break;
  829.  
  830.                     case SCROLLER_KIND:
  831.  
  832.                         if(Node->Special.Scroller.FullSize)
  833.                         {
  834.                             if(Node->Special.Scroller.Vertical)
  835.                             {
  836.                                 NewGadget.ng_TopEdge    = Node->Special.Scroller.Parent->Top;
  837.                                 NewGadget.ng_Height        = Node->Special.Scroller.Parent->Height;
  838.                             }
  839.                             else
  840.                             {
  841.                                 NewGadget.ng_LeftEdge    = Node->Special.Scroller.Parent->Left;
  842.                                 NewGadget.ng_Width        = Node->Special.Scroller.Parent->Width;
  843.                             }
  844.                         }
  845.  
  846.                         Gadget = CreateGadget(SCROLLER_KIND,Handle->Previous,&NewGadget,
  847.                             GA_RelVerify,    Node->Special.Scroller.RelVerify,
  848.                             GA_Immediate,    Node->Special.Scroller.Immediate,
  849.                             GTSC_Top,        Node->Current,
  850.                             GTSC_Total,        Node->Max,
  851.                             GTSC_Visible,    Node->Special.Scroller.Visible,
  852.                             PGA_Freedom,    Node->Special.Scroller.Vertical ? LORIENT_VERT : LORIENT_HORIZ,
  853.  
  854.                             Node->Special.Scroller.Arrows ? GTSC_Arrows : TAG_IGNORE,Node->Special.Scroller.ArrowSize,
  855.                         TAG_MORE,Tags);
  856.  
  857.                         break;
  858.  
  859.                     case FRACTION_KIND:
  860.                     case STRING_KIND:
  861.                     {
  862.                         STRPTR String;
  863.  
  864.                         String = Node->Special.String.String;
  865.  
  866.                         if(Node->Type == FRACTION_KIND)
  867.                         {
  868.                             UBYTE DecimalPoint;
  869.  
  870.                             LTP_CopyFraction(Node->Special.String.RealString,String);
  871.                             String = Node->Special.String.RealString;
  872.  
  873.                             DecimalPoint = LTP_DecimalPoint[0];
  874.  
  875.                             if(DecimalPoint != '.')
  876.                             {
  877.                                 LONG i;
  878.  
  879.                                 for(i = 0 ; i < strlen(String) ; i++)
  880.                                 {
  881.                                     if(String[i] == '.')
  882.                                     {
  883.                                         String[i] = DecimalPoint;
  884.                                         break;
  885.                                     }
  886.                                 }
  887.                             }
  888.  
  889.                             if(Node->Special.String.IncrementerHook)
  890.                             {
  891.                                 NewGadget.ng_Width -= 4 + Handle->GlyphWidth + 4;
  892.                                 NewGadget.ng_Width -= 4 + Handle->GlyphWidth + 4;
  893.                             }
  894.                         }
  895.  
  896.                         if(Node->Special.String.LinkID != -1)
  897.                         {
  898.                             ObjectNode *ListView = LTP_FindNode(Handle,Node->Special.String.LinkID);
  899.  
  900.                             if(ListView)
  901.                             {
  902.                                 NewGadget.ng_LeftEdge    = ListView->Left;
  903.                                 NewGadget.ng_TopEdge    = ListView->Top + ListView->Height;
  904.                                 NewGadget.ng_Width        = ListView->Width;
  905.                             }
  906.                         }
  907.  
  908.                         if(Node->Special.String.UsePicker)
  909.                             NewGadget.ng_Width -= LTP_GetPickerSize(Handle);
  910.  
  911.                         if(Gadget = CreateGadget(STRING_KIND,Handle->Previous,&NewGadget,
  912.                             GTST_String,            String,
  913.                             GTST_MaxChars,            Node->Special.String.MaxChars,
  914.                             GTST_EditHook,            Node->Special.String.EditHook ? Node->Special.String.EditHook : Handle->StandardEditHook,
  915.                             GA_Immediate,            TRUE,
  916.                             STRINGA_Justification,    Node->Special.String.Justification,
  917.                         TAG_MORE,Tags))
  918.                         {
  919.                             if(!V39)
  920.                                 Gadget->Activation |= GACT_IMMEDIATE;
  921.  
  922.                             if(Node->Special.String.UsePicker)
  923.                             {
  924.                                 Handle->Previous = Gadget;
  925.  
  926.                                 Extra = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_PICKER,0);
  927.  
  928.                                 if(!Extra)
  929.                                     Gadget = NULL;
  930.  
  931.                                 Node->Special.String.Picker = Extra;
  932.                             }
  933.                             else
  934.                             {
  935.                                 if(Node->Type == FRACTION_KIND && Node->Special.String.IncrementerHook)
  936.                                 {
  937.                                     Handle->Previous = Gadget;
  938.  
  939.                                     if(Node->Special.String.LeftIncrementer = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_LEFTINCREMENTER,-1))
  940.                                     {
  941.                                         Handle->Previous = Node->Special.String.LeftIncrementer;
  942.  
  943.                                         if(Node->Special.String.RightIncrementer = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_RIGHTINCREMENTER,1))
  944.                                             Extra = Node->Special.String.RightIncrementer;
  945.                                         else
  946.                                             Gadget = NULL;
  947.                                     }
  948.                                     else
  949.                                         Gadget = NULL;
  950.                                 }
  951.                             }
  952.                         }
  953.  
  954.                         break;
  955.                     }
  956.  
  957.                     #ifdef DO_PASSWORD_KIND
  958.                     {
  959.                         case PASSWORD_KIND:
  960.                         {
  961.                             LONG Len;
  962.  
  963.                             if(Len = strlen(Node->Special.String.RealString))
  964.                                 memset(Node->Special.String.Original,'·',Len);
  965.  
  966.                             Node->Special.String.Original[Len] = 0;
  967.  
  968.                             if(Gadget = CreateGadget(STRING_KIND,Handle->Previous,&NewGadget,
  969.                                 GTST_String,            Node->Special.String.Original,
  970.                                 GTST_MaxChars,            Node->Special.String.MaxChars,
  971.                                 GTST_EditHook,            &Handle->PasswordEditHook,
  972.                                 GA_Immediate,            TRUE,
  973.                                 STRINGA_Justification,    Node->Special.String.Justification,
  974.                             TAG_MORE,Tags))
  975.                             {
  976.                                 if(!V39)
  977.                                     Gadget->Activation |= GACT_IMMEDIATE;
  978.                             }
  979.  
  980.                             break;
  981.                         }
  982.                     }
  983.                     #endif
  984.  
  985.                     case INTEGER_KIND:
  986.  
  987.                         if(Node->Special.Integer.UseIncrementers)
  988.                         {
  989.                             NewGadget.ng_Width -= 4 + Handle->GlyphWidth + 4;
  990.                             NewGadget.ng_Width -= 4 + Handle->GlyphWidth + 4;
  991.  
  992.                             if(Node->Special.Integer.IncrementerHook)
  993.                             {
  994.                                 LONG Value;
  995.  
  996.                                 Value = (LONG)CallHookPkt(Node->Special.Integer.IncrementerHook,(APTR)Node->Special.Integer.Number,(APTR)INCREMENTERMSG_INITIAL);
  997.  
  998.                                 if(Value < Node->Min)
  999.                                     Value = Node->Min;
  1000.                                 else
  1001.                                 {
  1002.                                     if(Value > Node->Max)
  1003.                                         Value = Node->Max;
  1004.                                 }
  1005.  
  1006.                                 Node->Special.Integer.Number = Value;
  1007.                             }
  1008.                         }
  1009.  
  1010.                         #ifndef DO_HEXHOOK
  1011.                         {
  1012.                             Gadget = CreateGadget(INTEGER_KIND,Handle->Previous,&NewGadget,
  1013.                                 GTIN_Number,            Node->Special.Integer.Number,
  1014.                                 GTIN_MaxChars,            Node->Special.Integer.MaxChars,
  1015.                                 GTIN_EditHook,            Node->Special.Integer.EditHook ? Node->Special.Integer.EditHook : Handle->StandardEditHook,
  1016.                                 GA_Immediate,            TRUE,
  1017.                                 STRINGA_Justification,    Node->Special.Integer.Justification,
  1018.                             TAG_MORE,Tags);
  1019.                         }
  1020.                         #else
  1021.                         {
  1022.                             if(Node->Special.Integer.EditHook)
  1023.                             {
  1024.                                 Gadget = CreateGadget(INTEGER_KIND,Handle->Previous,&NewGadget,
  1025.                                     GTIN_Number,            Node->Special.Integer.Number,
  1026.                                     GTIN_MaxChars,            Node->Special.Integer.MaxChars,
  1027.                                     GTIN_EditHook,            Node->Special.Integer.EditHook,
  1028.                                     GA_Immediate,            TRUE,
  1029.                                     STRINGA_Justification,    Node->Special.Integer.Justification,
  1030.                                 TAG_MORE,Tags);
  1031.                             }
  1032.                             else
  1033.                             {
  1034.                                 UBYTE LocalBuffer[20];
  1035.  
  1036.                                 SPrintf(LocalBuffer,"%ld",Node->Special.Integer.Number);
  1037.  
  1038.                                 Gadget = CreateGadget(STRING_KIND,Handle->Previous,&NewGadget,
  1039.                                     GTST_String,            LocalBuffer,
  1040.                                     GTST_MaxChars,            Node->Special.Integer.MaxChars,
  1041.                                     GTST_EditHook,            &Handle->HexEditHook,
  1042.                                     GA_Immediate,            TRUE,
  1043.                                     STRINGA_Justification,    Node->Special.Integer.Justification,
  1044.                                 TAG_MORE,Tags);
  1045.                             }
  1046.  
  1047.                             if(Gadget)
  1048.                             {
  1049.                                 struct StringInfo *StringInfo = (struct StringInfo *)Gadget->SpecialInfo;
  1050.  
  1051.                                 StringInfo->LongInt = Node->Special.Integer.Number;
  1052.                             }
  1053.                         }
  1054.                         #endif /* DO_HEXHOOK */
  1055.  
  1056.                         if(Gadget)
  1057.                         {
  1058.                             if(!V39)
  1059.                                 Gadget->Activation |= GACT_IMMEDIATE;
  1060.  
  1061.                             if(Node->Special.Integer.UseIncrementers)
  1062.                             {
  1063.                                 Handle->Previous = Gadget;
  1064.  
  1065.                                 if(Node->Special.Integer.LeftIncrementer = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_LEFTINCREMENTER,-1))
  1066.                                 {
  1067.                                     Handle->Previous = Node->Special.Integer.LeftIncrementer;
  1068.  
  1069.                                     if(Node->Special.Integer.RightIncrementer = LTP_CreateExtraObject(Handle,Node,Gadget,&NewGadget,IMAGECLASS_RIGHTINCREMENTER,1))
  1070.                                         Extra = Node->Special.Integer.RightIncrementer;
  1071.                                     else
  1072.                                         Gadget = NULL;
  1073.                                 }
  1074.                                 else
  1075.                                     Gadget = NULL;
  1076.                             }
  1077.                         }
  1078.  
  1079.                         break;
  1080.                 }
  1081.  
  1082.                 if(Gadget != NULL)
  1083.                 {
  1084.                     Handle->GadgetArray[Handle->Index++] = Gadget;
  1085.  
  1086.                     Node->Host = Gadget;
  1087.  
  1088.                     #ifdef DO_BOOPSI_KIND
  1089.                     {
  1090.                         if(Node->Type == BOOPSI_KIND || Node->Type == POPUP_KIND || Node->Type == TAB_KIND || Node->Type == LEVEL_KIND)
  1091.                         {
  1092.                             Handle->BOOPSIPrevious = (Object *)Gadget;
  1093.  
  1094.                             if(!Handle->BOOPSIList)
  1095.                                 Handle->BOOPSIList = (Object *)Gadget;
  1096.                         }
  1097.                         else
  1098.                         {
  1099.                             if(Extra)
  1100.                                 Handle->Previous = Extra;
  1101.                             else
  1102.                                 Handle->Previous = Gadget;
  1103.                         }
  1104.                     }
  1105.                     #else
  1106.                     {
  1107.                         if(Extra)
  1108.                             Handle->Previous = Extra;
  1109.                         else
  1110.                             Handle->Previous = Gadget;
  1111.                     }
  1112.                     #endif    /* DO_BOOPSI_KIND */
  1113.                 }
  1114.                 else
  1115.                 {
  1116.                     Handle->Failed = TRUE;
  1117.  
  1118.                     return;    /* Note: must return since we are in a loop that
  1119.                              *       creates all gadgets for the current page.
  1120.                              */
  1121.                 }
  1122.             }
  1123.         }
  1124.     }
  1125. }
  1126.